// Copyright (c) 2025, 大连理工大学 (Dalian University of Technology)
//
// Licensed under the Mulan PSL v2.
// You can use this file according to the terms and conditions of the Mulan PSL v2.
// You may obtain a copy of the License at
//
//     http://license.coscl.org.cn/MulanPSL2
//
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. SEE THE MULAN PSL v2
// FOR MORE DETAILS.

#include "DBManager/Service/Result/Nodal/EIGENVECTOR_CPLXService.h"

#include "DBManager/IService/Result/IResultDomainsService.h"

using namespace SG::DBManager;

// 注册服务
SERVICE_REG_WITH_DBM_IMPL (EIGENVECTOR_CPLXService, IEIGENVECTOR_CPLXRepository)

SERVICE_REG_RESULT (EIGENVECTOR_CPLXService)

EIGENVECTOR_CPLXService::EIGENVECTOR_CPLXService (DBServiceFactory* const dbServiceFactory, IEIGENVECTOR_CPLXRepository& repos)
    : m_dbServiceFactory (dbServiceFactory), m_repository (repos)
{}

EIGENVECTOR_CPLXService::~EIGENVECTOR_CPLXService () = default;
SG::DataStructure::Common::Status EIGENVECTOR_CPLXService::Find (const SG::DataStructure::FEM::SOLType analysisType,
                                                                 const SG::DataStructure::Common::Id         subcaseId,
                                                                 const SG::DataStructure::Common::I64        mode,
                                                                 std::vector<DataType>& _OUT                 entity)
{
    auto domainService = m_dbServiceFactory->get<IResultDomainsService> ();

    SG::DataStructure::Post::ResultDomains domain;

    if (domainService->Find ({ analysisType, subcaseId, static_cast<SG::DataStructure::Common::Real> (mode) }, _OUT domain)
        == SG::DataStructure::Common::Status::STATUS_Failure)
    {
        return SG::DataStructure::Common::Status::STATUS_Failure;
    }

    return this->m_repository.FindByDomainId (domain.m_id, entity);
}

SG::DataStructure::Common::Status EIGENVECTOR_CPLXService::Add (const SG::DataStructure::FEM::SOLType analysisType,
                                                                const SG::DataStructure::Common::Id         subcaseId,
                                                                const SG::DataStructure::Common::I64        mode,
                                                                const std::complex<double>                  eigen,
                                                                std::vector<DataType>&                      entity)
{
    auto domainService = m_dbServiceFactory->get<IResultDomainsService> ();

    SG::DataStructure::Post::ResultDomains domainData;

    if (domainService->Find ({ analysisType, subcaseId, static_cast<SG::DataStructure::Common::Real> (mode) }, _OUT domainData)
        == SG::DataStructure::Common::Status::STATUS_Failure)
    {
        domainData.m_Analysis          = SG::DataStructure::Post::ConvertSOLTypeToAnalysisType(analysisType);
        domainData.m_Subcase           = subcaseId;
        domainData.m_Mode              = mode;
        domainData.m_TimeFrequencyEigr = eigen.real ();
        domainData.m_Eigi              = eigen.imag ();
        if (domainService->Add (domainData) == SG::DataStructure::Common::Status::STATUS_Failure)
        {
            SGWarn << __FILE__ << ":" << __LINE__ << " add domain failed！";
            return SG::DataStructure::Common::Status::STATUS_Failure;
        }
    }

    return this->m_repository.Add (domainData.m_id, entity);
}
